"use strict";

var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../../ui");
var _util = require("../../src/util");
var _dom = require("../../../ui/src/dom");
var _utils = require("../../../ui/src/utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
  renderer,
  hooks
} = _ui.VxeUI;
const tableFilterMethodKeys = ['openFilter', 'setFilter', 'clearFilter', 'saveFilterPanel', 'resetFilterPanel', 'getCheckedFilters', 'updateFilterOptionStatus'];
hooks.add('tableFilterModule', {
  setupTable($xeTable) {
    const {
      props,
      reactData,
      internalData
    } = $xeTable;
    const {
      refElem,
      refTableFilter
    } = $xeTable.getRefMaps();
    const {
      computeFilterOpts,
      computeMouseOpts
    } = $xeTable.getComputeMaps();
    // 确认筛选
    const handleFilterConfirmFilter = evnt => {
      const {
        filterStore
      } = reactData;
      filterStore.options.forEach(option => {
        option.checked = option._checked;
      });
      $xeTable.confirmFilterEvent(evnt);
    };
    // （单选）筛选发生改变
    const changeRadioOption = (evnt, checked, item) => {
      const {
        filterStore
      } = reactData;
      filterStore.options.forEach(option => {
        option._checked = false;
      });
      item._checked = checked;
      $xeTable.checkFilterOptions();
      handleFilterConfirmFilter(evnt);
    };
    // （多选）筛选发生改变
    const changeMultipleOption = (evnt, checked, item) => {
      item._checked = checked;
      $xeTable.checkFilterOptions();
    };
    /**
     * 重置筛选
     * 当筛选面板中的重置按钮被按下时触发
     * @param {Event} evnt 事件
     */
    const handleFilterResetFilter = evnt => {
      const {
        filterStore
      } = reactData;
      $xeTable.handleClearFilter(filterStore.column);
      $xeTable.confirmFilterEvent(evnt);
    };
    const filterPrivateMethods = {
      checkFilterOptions() {
        const {
          filterStore
        } = reactData;
        filterStore.isAllSelected = filterStore.options.every(item => item._checked);
        filterStore.isIndeterminate = !filterStore.isAllSelected && filterStore.options.some(item => item._checked);
      },
      /**
       * 点击筛选事件
       * 当筛选图标被点击时触发
       * 更新选项是否全部状态
       * 打开筛选面板
       * @param {Event} evnt 事件
       * @param {ColumnInfo} column 列配置
       * @param {Object} params 参数
       */
      triggerFilterEvent(evnt, column, params) {
        const {
          initStore,
          filterStore
        } = reactData;
        const {
          elemStore
        } = internalData;
        if (filterStore.column === column && filterStore.visible) {
          filterStore.visible = false;
        } else {
          const {
            clientY,
            pageX
          } = evnt;
          const el = refElem.value;
          const tableRect = el.getBoundingClientRect();
          const targetElem = evnt.target;
          const {
            visibleWidth
          } = (0, _dom.getDomNode)();
          const {
            filters,
            filterMultiple,
            filterRender
          } = column;
          const compConf = (0, _utils.isEnableConf)(filterRender) ? renderer.get(filterRender.name) : null;
          const frMethod = column.filterRecoverMethod || (compConf ? compConf.tableFilterRecoverMethod || compConf.filterRecoverMethod : null);
          internalData._currFilterParams = params;
          Object.assign(filterStore, {
            multiple: filterMultiple,
            options: filters,
            column,
            style: null
          });
          // 复原状态
          filterStore.options.forEach(option => {
            const {
              _checked,
              checked
            } = option;
            option._checked = checked;
            if (!checked && _checked !== checked) {
              if (frMethod) {
                frMethod({
                  option,
                  column,
                  $table: $xeTable
                });
              }
            }
          });
          this.checkFilterOptions();
          filterStore.visible = true;
          initStore.filter = true;
          (0, _vue.nextTick)(() => {
            const headerScrollElem = (0, _util.getRefElem)(elemStore['main-header-scroll']);
            if (!headerScrollElem) {
              return;
            }
            const tableFilter = refTableFilter.value;
            const filterWrapperElem = tableFilter ? tableFilter.$el : null;
            if (!filterWrapperElem) {
              return;
            }
            const filterWidth = filterWrapperElem.offsetWidth;
            const filterHeadElem = filterWrapperElem.querySelector('.vxe-table--filter-header');
            const filterFootElem = filterWrapperElem.querySelector('.vxe-table--filter-footer');
            const centerWidth = filterWidth / 2;
            const minMargin = 10;
            const maxLeft = el.clientWidth - filterWidth - minMargin;
            let left, right;
            const thEl = targetElem.offsetParent;
            const trEl = thEl.offsetParent;
            const style = {
              top: `${targetElem.offsetTop + thEl.offsetTop + targetElem.offsetHeight}px`
            };
            // 判断面板不能大于表格高度
            const maxHeight = Math.max(40, el.clientHeight - (clientY - tableRect.y) - (filterHeadElem ? filterHeadElem.clientHeight : 0) - (filterFootElem ? filterFootElem.clientHeight : 0) - 14);
            if (column.fixed === 'left') {
              left = targetElem.offsetLeft + thEl.offsetLeft - centerWidth;
            } else if (column.fixed === 'right') {
              right = thEl.offsetWidth - targetElem.offsetLeft + (trEl.offsetWidth - trEl.offsetLeft) - column.renderWidth - centerWidth;
            } else {
              left = targetElem.offsetLeft + thEl.offsetLeft - centerWidth - headerScrollElem.scrollLeft;
            }
            if (left) {
              const overflowWidth = pageX + filterWidth - centerWidth + minMargin - visibleWidth;
              if (overflowWidth > 0) {
                left -= overflowWidth;
              }
              style.left = `${Math.min(maxLeft, Math.max(minMargin, left))}px`;
            } else if (right) {
              const overflowWidth = pageX + filterWidth - centerWidth + minMargin - visibleWidth;
              if (overflowWidth > 0) {
                right += overflowWidth;
              }
              style.right = `${Math.max(minMargin, right)}px`;
            }
            filterStore.style = style;
            filterStore.maxHeight = maxHeight;
          });
        }
        $xeTable.dispatchEvent('filter-visible', {
          column,
          field: column.field,
          property: column.field,
          filterList: $xeTable.getCheckedFilters(),
          visible: filterStore.visible
        }, evnt);
      },
      handleClearFilter(column) {
        if (column) {
          const {
            filters,
            filterRender
          } = column;
          if (filters) {
            const compConf = (0, _utils.isEnableConf)(filterRender) ? renderer.get(filterRender.name) : null;
            const frMethod = column.filterResetMethod || (compConf ? compConf.tableFilterResetMethod || compConf.filterResetMethod : null);
            filters.forEach(item => {
              item._checked = false;
              item.checked = false;
              if (!frMethod) {
                item.data = _xeUtils.default.clone(item.resetValue, true);
              }
            });
            if (frMethod) {
              frMethod({
                options: filters,
                column,
                $table: $xeTable
              });
            }
          }
        }
      },
      handleColumnConfirmFilter(column, evnt) {
        const {
          mouseConfig
        } = props;
        const {
          scrollXLoad: oldScrollXLoad,
          scrollYLoad: oldScrollYLoad
        } = reactData;
        const filterOpts = computeFilterOpts.value;
        const mouseOpts = computeMouseOpts.value;
        const {
          field
        } = column;
        const values = [];
        const datas = [];
        column.filters.forEach(item => {
          if (item.checked) {
            values.push(item.value);
            datas.push(item.data);
          }
        });
        const filterList = $xeTable.getCheckedFilters();
        const params = {
          $table: $xeTable,
          $event: evnt,
          column,
          field,
          property: field,
          values,
          datas,
          filters: filterList,
          filterList
        };
        // 如果是服务端筛选，则跳过本地筛选处理
        if (!filterOpts.remote) {
          $xeTable.handleTableData(true);
          $xeTable.checkSelectionStatus();
        }
        if (mouseConfig && mouseOpts.area && $xeTable.handleFilterEvent) {
          $xeTable.handleFilterEvent(evnt, params);
        }
        if (evnt) {
          $xeTable.dispatchEvent('filter-change', params, evnt);
        }
        $xeTable.closeFilter();
        return $xeTable.updateFooter().then(() => {
          const {
            scrollXLoad,
            scrollYLoad
          } = reactData;
          if (oldScrollXLoad || scrollXLoad || oldScrollYLoad || scrollYLoad) {
            if (oldScrollXLoad || scrollXLoad) {
              $xeTable.updateScrollXSpace();
            }
            if (oldScrollYLoad || scrollYLoad) {
              $xeTable.updateScrollYSpace();
            }
            return $xeTable.refreshScroll();
          }
        }).then(() => {
          $xeTable.updateCellAreas();
          return $xeTable.recalculate(true);
        }).then(() => {
          // 存在滚动行为未结束情况
          setTimeout(() => $xeTable.recalculate(), 50);
        });
      },
      /**
       * 确认筛选
       * 当筛选面板中的确定按钮被按下时触发
       * @param {Event} evnt 事件
       */
      confirmFilterEvent(evnt) {
        const {
          filterStore
        } = reactData;
        const {
          column
        } = filterStore;
        $xeTable.handleColumnConfirmFilter(column, evnt);
      },
      handleFilterChangeRadioOption: changeRadioOption,
      handleFilterChangeMultipleOption: changeMultipleOption,
      // 筛选发生改变
      handleFilterChangeOption(evnt, checked, item) {
        const {
          filterStore
        } = reactData;
        if (filterStore.multiple) {
          changeMultipleOption(evnt, checked, item);
        } else {
          changeRadioOption(evnt, checked, item);
        }
      },
      handleFilterConfirmFilter,
      handleFilterResetFilter
    };
    const filterMethods = {
      /**
       * 手动弹出筛选面板
       * @param column
       */
      openFilter(fieldOrColumn) {
        const column = (0, _util.handleFieldOrColumn)($xeTable, fieldOrColumn);
        if (column && column.filters) {
          const {
            elemStore
          } = internalData;
          const {
            fixed
          } = column;
          return $xeTable.scrollToColumn(column).then(() => {
            const headerWrapperElem = (0, _util.getRefElem)(elemStore[`${fixed || 'main'}-header-wrapper`] || elemStore['main-header-wrapper']);
            if (headerWrapperElem) {
              const filterBtnElem = headerWrapperElem.querySelector(`.vxe-header--column.${column.id} .vxe-filter--btn`);
              (0, _dom.triggerEvent)(filterBtnElem, 'click');
            }
          });
        }
        return (0, _vue.nextTick)();
      },
      /**
       * 修改筛选条件列表
       * @param {ColumnInfo} fieldOrColumn 列或字段名
       * @param {Array} options 选项
       */
      setFilter(fieldOrColumn, options, isUpdate) {
        const column = (0, _util.handleFieldOrColumn)($xeTable, fieldOrColumn);
        if (column && column.filters) {
          column.filters = (0, _util.toFilters)(options || []);
          if (isUpdate) {
            return $xeTable.handleColumnConfirmFilter(column, new Event('click'));
          }
        }
        return (0, _vue.nextTick)();
      },
      /**
       * 清空指定列的筛选条件
       * 如果为空则清空所有列的筛选条件
       * @param {String} fieldOrColumn 列或字段名
       */
      clearFilter(fieldOrColumn) {
        const {
          filterStore
        } = reactData;
        const {
          tableFullColumn
        } = internalData;
        const filterOpts = computeFilterOpts.value;
        let column;
        if (fieldOrColumn) {
          column = (0, _util.handleFieldOrColumn)($xeTable, fieldOrColumn);
          if (column) {
            filterPrivateMethods.handleClearFilter(column);
          }
        } else {
          tableFullColumn.forEach(filterPrivateMethods.handleClearFilter);
        }
        if (!fieldOrColumn || column !== filterStore.column) {
          Object.assign(filterStore, {
            isAllSelected: false,
            isIndeterminate: false,
            style: null,
            options: [],
            column: null,
            multiple: false,
            visible: false
          });
        }
        if (!filterOpts.remote) {
          return $xeTable.updateData();
        }
        return (0, _vue.nextTick)();
      },
      saveFilterPanel() {
        handleFilterConfirmFilter(null);
        return (0, _vue.nextTick)();
      },
      resetFilterPanel() {
        handleFilterResetFilter(null);
        return (0, _vue.nextTick)();
      },
      getCheckedFilters() {
        const {
          tableFullColumn
        } = internalData;
        const filterList = [];
        tableFullColumn.forEach(column => {
          const {
            field,
            filters
          } = column;
          const valueList = [];
          const dataList = [];
          if (filters && filters.length) {
            filters.forEach(item => {
              if (item.checked) {
                valueList.push(item.value);
                dataList.push(item.data);
              }
            });
            if (valueList.length) {
              filterList.push({
                column,
                field,
                property: field,
                values: valueList,
                datas: dataList
              });
            }
          }
        });
        return filterList;
      },
      updateFilterOptionStatus(item, checked) {
        item._checked = checked;
        item.checked = checked;
        return (0, _vue.nextTick)();
      }
    };
    return Object.assign(Object.assign({}, filterMethods), filterPrivateMethods);
  },
  setupGrid($xeGrid) {
    return $xeGrid.extendTableMethods(tableFilterMethodKeys);
  }
});